package com.dy.排序.内排序.交换排序.快速排序;

import java.util.Arrays;

/*
通过一趟排序将要排序的数据分割成独立的两部分，其中一部分的所有数据都比另外一部分的所有数据都要小
然后再按此方法对这两部分数据分别进行快速排序，整个排序过程可以递归进行，以此达到整个数据变成有序序列。
 */
/*
1）设置两个变量i、j，排序开始的时候：i=0，j=N-1；
2）以第一个数组元素作为关键数据，赋值给key，即key=A[0]；
3）从j开始向前搜索，即由后开始向前搜索(j--)，找到第一个小于key的值A[j]，将A[j]的值赋给A[i]；
4）从i开始向后搜索，即由前开始向后搜索(i++)，找到第一个大于key的A[i]，将A[i]的值赋给A[j]；
5）重复第3、4步，直到i=j； (3,4步中，没找到符合条件的值，即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值，
使得j=j-1，i=i+1，直至找到为止。找到符合条件的值，进行交换的时候i， j指针位置不变。
另外，i==j这一过程一定正好是i+或j-完成的时候，此时令循环结束）。
 */
/*
空间复杂度：看做二叉树，高度为O（log2n)，所需空间也为O(log2n）
时间复杂读：最好情况：每次都分为两个等长序列，O(nlog2n)，最坏情况，有序时，变成冒泡，O(n2),平均O(nlog2n)
 */
public class QuickSort {
    public static void quickSort(int[] nums, int low, int high) {
        if(low<high) {
            int mid = digui(nums, low, high);
            quickSort(nums, low, mid - 1);
            quickSort(nums, mid + 1, high);
        }
    }

    private static int digui(int[] nums, int start, int end) {
        int i = start, j = end;
        int key = nums[start];
        while (i < j) {
            while (i < j && nums[j] > key) j--;
            if (i < j) {
                nums[i] = nums[j];
                i++;
            }
            while (i < j && nums[i] < key) i++;
            if (i < j) {
                nums[j] = nums[i];
                j--;
            }
        }
        nums[i] = key;
        return i;
    }

    public static void main(String[] args) {
        int nums[] = {3, 5, 4, 6, 3, 2, 1};
        quickSort(nums, 0, nums.length - 1);
        Arrays.stream(nums).forEach(System.out::println);
    }

}
